home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / graphics / qrt.lzh / INSTANCE.C < prev    next >
C/C++ Source or Header  |  1989-02-16  |  5KB  |  240 lines

  1.  
  2. /**********************************************************
  3.  
  4.     Routines for user-defined primitives (INSTANCE_OF)
  5.  
  6.  **********************************************************/
  7.  
  8. #include "qrt.h"
  9.  
  10. float Get_Next_Num(), IsPos();
  11. char  *Get_Next_Name();
  12.  
  13. /* #define INSTANCEDEBUG TRUE */
  14.  
  15. /**********************************************************
  16.  
  17.      Returns a pointer to the object in the object
  18.      tree with the given name.
  19.  
  20.  **********************************************************/
  21.  
  22.  
  23. OBJ_PTR Name_Find(obj,name)
  24.   OBJ_PTR obj;
  25.   char *name;
  26. {
  27.   OBJ_PTR temp;
  28.  
  29.   if (obj==NULL) return(NULL);
  30.  
  31.   if (obj->name!=NULL)
  32.     if (strcmp(name,obj->name)==0) return(obj);
  33.  
  34.   if (obj->child != NULL)
  35.     if ((temp=Name_Find(obj->child,name))!=NULL)
  36.       return(temp);
  37.  
  38.   if (obj->nextobj != NULL)
  39.     if ((temp=Name_Find(obj->nextobj,name))!=NULL)
  40.       return(temp);
  41.  
  42.   return(NULL);
  43. }
  44.  
  45.  
  46. /**********************************************************
  47.  
  48.     Copies a given sub-tree and returns a pointer to
  49.     the copy.    Always pass fflag=TRUE
  50.  
  51.  **********************************************************/
  52.  
  53. OBJ_PTR Subtree_Copy(obj, fflag)
  54.   OBJ_PTR obj;
  55.   int fflag;
  56. {
  57.   OBJ_PTR newobj, new_obj();
  58.  
  59.   if (obj==NULL) return(NULL);
  60.  
  61. # ifdef INSTANCEDEBUG
  62.     printf("SUBTREECOPY: name = %s\n",obj->name);
  63. # endif
  64.  
  65.   newobj = new_obj( obj->type,         /* make new obj */
  66.                     &(obj->loc),
  67.                     &(obj->vect1),
  68.                     &(obj->vect2),
  69.                     &(obj->vect3),
  70.                     &(obj->cinfo),
  71.                     obj->pattern,
  72.                     obj->remove,
  73.                     NULL,              /* no name here */
  74.                     &(obj->upper),
  75.                     &(obj->lower),
  76.                     obj->cterm,
  77.                     obj->xmult,
  78.                     obj->ymult );
  79.  
  80.   newobj->child   = Subtree_Copy(obj->child,FALSE);
  81.  
  82.   if (!fflag)
  83.     newobj->nextobj = Subtree_Copy(obj->nextobj,FALSE);
  84.   else
  85.     newobj->nextobj = NULL;
  86.  
  87.   return(newobj);
  88. }
  89.  
  90. /**********************************************************
  91.  
  92.           Offsets sub-tree by offset distance units
  93.           ALWAYS pass fflag = TRUE
  94.  
  95.  **********************************************************/
  96.  
  97. Subtree_Offset(obj,offset,fflag)
  98.   OBJ_PTR obj;
  99.   VECT_PTR offset;
  100.   int fflag;
  101. {
  102.   if (obj==NULL) return;
  103.  
  104. # ifdef INSTANCEDEBUG
  105.     printf("SUBTREEOFFSET: type = %d offset = %f %f %f\n",
  106.            obj->type,
  107.            offset->x,
  108.            offset->y,
  109.            offset->z);
  110. # endif
  111.  
  112.   (*(ObjData[obj->type].Offset))(obj,offset);
  113.  
  114.   Subtree_Offset(obj->child,offset,FALSE);
  115.  
  116.   if (!fflag)
  117.     Subtree_Offset(obj->nextobj,offset,FALSE);
  118. }
  119.  
  120. /**********************************************************
  121.  
  122.           Scales a sub-tree by mult distance units
  123.           ALWAYS pass fflag = TRUE
  124.  
  125.  **********************************************************/
  126.  
  127. Subtree_Scale(obj,mult,fflag)
  128.   OBJ_PTR obj;
  129.   VECT_PTR mult;
  130.   int fflag;
  131. {
  132.   if (obj==NULL) return;
  133.  
  134. # ifdef INSTANCEDEBUG
  135.     printf("SUBTREESCALE: type = %d mult = %f %f %f\n",
  136.            obj->type,
  137.            mult->x,
  138.            mult->y,
  139.            mult->z);
  140. # endif
  141.  
  142.   (*(ObjData[obj->type].Resize))(obj,mult);
  143.  
  144.   Subtree_Scale(obj->child,mult,FALSE);
  145.  
  146.   if (!fflag)
  147.     Subtree_Scale(obj->nextobj,mult,FALSE);
  148. }
  149.  
  150. /**********************************************************
  151.  
  152.   Load an "Instance_of" structure.  This really makes a
  153.   copy of another part of the tree, offsets it, and returns
  154.   a pointer to this copy.  All "name" fields for the copy
  155.   are set to null to avoid duplicate names.  Also, a new
  156.   scale factor can be specified (default 1).
  157.  
  158.  **********************************************************/
  159.  
  160. OBJ_PTR Get_Instance_Of()
  161. {
  162.   char str[SLEN], *name;
  163.   int end, f, found;
  164.   VECTOR offset, mult;
  165.   OBJ_PTR source, dest;
  166.  
  167.   end=f=0;
  168.   mult.x = mult.y = mult.z = 1.00;
  169.  
  170.   GetLeftParen();
  171.  
  172.   while (!end && !feof(stdin)) {
  173.     GetToken(str);
  174.  
  175.     found = FALSE;
  176.     if (strcmp(str,"NAME")==0) {
  177.       name = Get_Next_Name();
  178.       f|=1; found = TRUE;
  179.     }
  180.  
  181.     if ((strcmp(str,"POS")==0)      ||
  182.         (strcmp(str,"LOC")==0)      ||
  183.         (strcmp(str,"POSITION")==0) ||
  184.         (strcmp(str,"LOCATION")==0)) {
  185.  
  186.       GetVector(&offset);
  187.       f|=2; found = TRUE;
  188.     }
  189.  
  190.     if (strcmp(str,"SCALE")==0) {
  191.       GetVector(&mult);
  192.       found = TRUE;
  193.     }
  194.  
  195.     if (strcmp(str,")")==0) { end=1; found = TRUE; }
  196.  
  197.     if (!found) Error(UNDEFINED_PARAM,1203);
  198.  
  199.   }
  200.  
  201.   if (f!=3) Error(TOO_FEW_PARMS,1204);
  202.  
  203. # ifdef INSTANCEDEBUG
  204.     printf("GET_INSTANCE: offset = %f %f %f\n",
  205.            offset.x,
  206.            offset.y,
  207.            offset.z);
  208. # endif
  209.  
  210.   if ((source = Name_Find(THEWORLD.instances,name))==NULL)
  211.     Error(UNDEFINED_NAME,1205);
  212.  
  213.   if ((dest = Subtree_Copy(source,TRUE))==NULL)
  214.     Error(INTERNAL_ERROR,1206);
  215.  
  216.   /* scale the subtree */
  217.  
  218. # ifdef INSTANCEDEBUG
  219.     printf("scaling...\n");
  220. # endif
  221.  
  222.   Subtree_Scale(dest,&mult,TRUE);
  223.  
  224. # ifdef INSTANCEDEBUG
  225.     printf("Offsetting...\n");
  226. # endif
  227.  
  228.   /* move the subtree */
  229.  
  230.   Subtree_Offset(dest,&offset,TRUE);
  231.  
  232. # ifdef INSTANCEDEBUG
  233.     printf("returning\n");
  234. # endif
  235.  
  236.   return(dest);
  237. }
  238.  
  239.  
  240.